/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       mana_source.h

	$Header: /game/mana_source.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "mana_source.h"

#include "adv_object_type.h"
#include "adventure_frame.h"
#include "adventure_sounds.h"
#include "army.h"
#include "basic_dialog.h"
#include "bitmap_group_cache.h"
#include "bitmap_group_window.h"
#include "creature_icon_window.h"
#include "external_string.h"
#include "format_string.h"
#include "game_replace_keywords.h"
#include "hero.h"
#include "mouse_event.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "replace_keywords.h"
#include "simple_dialog.h"
#include "standard_fonts.h"
#include "text_window.h"

static t_object_registration<t_mana_source> k_registration( k_adv_object_mana_recharger);

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
t_mana_source::t_mana_source( std::string const& model_name )
             : t_stationary_adventure_object( model_name )
{
}


// -------------------------------------------------------
// create a single window from a group of windows
// -------------------------------------------------------
extern t_bitmap_group_cache k_stat_icons_82;
extern t_external_string const k_text_spell_points;

static void show_bonus( t_hero* hero, int amount, t_basic_dialog* dialog )
{
	t_window*						parent;
	t_screen_rect                   rect;
	t_screen_point                  center;

	// create invisible parent to house 2 icons and a text window
	parent = new t_window( t_screen_rect(0,0,0,0), t_window::k_completely_transparent, dialog );
	// create and add in the mana icon

	t_bitmap_group_window* mana_icon;
	t_bitmap_group_ptr     bitmaps;
	std::string            text;

	bitmaps = k_stat_icons_82.get();
	mana_icon = new t_bitmap_group_window( bitmaps, t_screen_point(0,0), "spell_points", parent );
	text = format_string( "%+i %s", amount, k_text_spell_points.c_str() );
	
	center.x = mana_icon->get_width() / 2;
	center.y = mana_icon->get_height() + 5;

	// create and add the text window do display the bonus
	int const      k_text_width = 34;
	int const      k_text_height = 18;
	t_text_window* text_window;
	t_screen_rect  text_rect( 0, mana_icon->get_height() + 5, mana_icon->get_width(), 
							  mana_icon->get_height() + 5 + k_text_height);

	text = format_string("+%i", amount );

	text_window = new t_text_window( get_font( text_rect.height() ), text_rect, parent, 
		                             text, t_pixel_24(0,0,0) );
	text_window->set_drop_shadow( false );
	text_window->set_center_horizontal();

	// add the portrait window
	t_window* window;

	center.y = text_rect.bottom + 5;

	rect = t_screen_rect(0,0,52,52);
	window = new t_creature_icon_window( rect, parent, hero );

	rect = window->get_client_rect();
	rect -= t_screen_point( rect.width() / 2, 0 );
	rect += center;
	window->move( rect );
	parent->set_size_from_children();
	dialog->add_display_window( parent, hero->get_name() );
}

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
void t_mana_source::activate_trigger( t_army* army, t_adv_map_point const& point, 
	                                  t_direction direction, t_adventure_frame* frame )
{
	t_creature_array& creatures = army->get_creatures();

	int                  i;
	t_hero*              hero;
	std::vector<t_hero*> heroes;
	int                  max_benefit_level = get_charge_rate();
	bool				 any_heroes = false;
	int                  hero_charge_level;
	int                  max_mana;
	int                  current_mana;
	int					 new_mana;
	int                  mana_gained;
	t_basic_dialog*      dialog = 0;

	if (!army->get_owner()->is_computer())
	{
		dialog = new t_basic_dialog;
		dialog->add_ok_button();
	}
	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero = creatures[i].get_hero();
		if (hero == 0)
			continue;
		any_heroes = true;

		if (hero->is_dead())
			continue;

		current_mana		= hero->get_spell_points();
		max_mana			= hero->get_maximum_spell_points();
		hero_charge_level	= hero->get_well_recharge_level();
		if (hero_charge_level >= max_benefit_level)
			continue;

		mana_gained	= (max_mana * (max_benefit_level - hero_charge_level))/100;
		new_mana = current_mana + mana_gained;
		if (new_mana > max_mana)
		{
			new_mana = max_mana;
			mana_gained = new_mana - current_mana;
		}
		if (mana_gained <= 0)
			continue;

		hero->set_spell_points( new_mana );
		hero->set_well_recharge_level( hero_charge_level + mana_gained * 100 / max_mana );
		heroes.push_back( hero );
		if (dialog != 0)
		{
			show_bonus( hero, mana_gained, dialog );
		}
	}
	if (!army->get_owner()->is_computer())
	{
		t_sound_cache music = get_music_playing();
		stop_music();
		get_dialog_sound( k_dialog_sound_mana )->play( get_sound_volume() );
		if (!any_heroes)
		{
			ok_dialog( replace_text(get_text("no_heroes")), get_dialog_bottom( point ) );
			play_music( music );
			return;
		}
		if (heroes.size() == 0)
		{
			ok_dialog( replace_text(get_text( "full" )), get_dialog_bottom( point ));
//			ok_dialog( replace_text(get_text( "visited" )), get_dialog_bottom( point ) );
			play_music( music );
			return;
		}

		std::string text;
		std::string charge_rate_string = format_string( "%i%%", get_charge_rate() );

		text = replace_keywords( get_text( "initial" ), heroes );
		text = replace_text( text );
		get_adventure_frame()->update();
		dialog->set_text( text );
		dialog->set_title( get_name() );
		dialog->open( get_dialog_bottom( point ), true, k_align_bottom );
		dialog->run_modal();
		play_music( music );
	}
}

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
int t_mana_source::get_charge_rate() const
{
	static int const charge_rates[] = { 35, 50, 65, 80, 100 };

	int type = get_major_subtype();

	assert( type < 5 );
	return charge_rates[type];
}

// -------------------------------------------------------------
// object which only gives a benefit once
// -------------------------------------------------------------
bool t_mana_source::benefits( t_army* army ) const
{
	if (army == 0)
		return false;

	t_creature_array& creatures = army->get_creatures();
	int               max_benefit_level = get_charge_rate();

	for (int i = 0; i < t_creature_array::k_size; i++)
	{
		const t_hero* hero = creatures[i].get_hero();
		if (hero == 0)
			continue;

		const int current_mana = hero->get_spell_points();
		const int max_mana = hero->get_maximum_spell_points();
		int			recharge_level = hero->get_well_recharge_level();

		if ( current_mana < max_mana && recharge_level < get_charge_rate())
			return true;
	}

	return false;
}

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
//extern t_external_string const k_text_visited;
extern t_external_string const k_text_no_benefit( "no_benefit.object" );

std::string t_mana_source::get_balloon_help() const
{
	const t_adventure_frame*  adventure_frame = get_adventure_frame();

	std::string result = t_stationary_adventure_object::get_name();

	if (!benefits( adventure_frame->get_selected_army() ))
		result += " " + k_text_no_benefit.get();
	return result;
}

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
std::string t_mana_source::replace_text( std::string const& text ) const
{
	std::string charge_rate = format_string( "%i%%", get_charge_rate() );

	return replace_keywords( text, "%object_name", t_stationary_adventure_object::get_name(),
		 				     "%percentage", charge_rate );
}

// ------------------------------------------------------------------
// various wells which recharge mana
// ------------------------------------------------------------------
void t_mana_source::right_click( t_mouse_event const& event,
							     t_adventure_frame* adventure_frame )
{
	std::string text;

	if (!benefits( adventure_frame->get_selected_army() ))
		text = get_text( "help_visited" );
	else
		text = get_text( "help" );
	text = replace_text( text );
	show_popup_text( text, event.screen_point );
}

